<template>
  <div class="custom-upload">
    <template v-if="type === 'dropdown'">
      <el-dropdown
        :size="size"
        split-button
        type="default"
        trigger="click"
        :class="{ 'hide-list': fileList.length <= 0 }"
      >
        <el-upload
          :name="name"
          style="width: 100%"
          :headers="headers"
          :action="action"
          :data="data"
          :limit="limit"
          :disabled="disabled"
          :multiple="multiple"
          :accept="accept"
          :show-file-list="false"
          :file-list="fileList"
          :before-upload="beforeUpload"
          :before-remove="beforeRemove"
          :on-exceed="onUploadLimit"
          :on-success="onUploadSuccess"
          :on-remove="onRemoveFile"
          :on-error="onUploadError"
        >
          <el-row type="flex" align="middle">
            <span class="upload-btn">
              上传文件
              <div class="file-count" v-if="uploadWidget.fileList.length > 0">
                {{ fileList.length }}
              </div>
            </span>
          </el-row>
        </el-upload>
        <el-dropdown-menu slot="dropdown">
          <el-dropdown-item v-for="(item, index) in fileList" :key="item.url">
            <el-row
              class="dropdown-file-item"
              type="flex"
              justify="space-between"
              align="middle"
              style="height: 36px"
            >
              <span @click="onPreviewClick(item, fileList)" style="flex-grow: 1">
                {{ item.name }}
              </span>
              <i
                v-if="!disabled"
                class="el-icon-error"
                style="margin-left: 8px"
                @click.stop="onRemoveFile(item, uploadWidget.fileList)"
              />
            </el-row>
            <div v-if="index !== fileList.length - 1" style="height: 1px; background: #eeeff1" />
          </el-dropdown-item>
        </el-dropdown-menu>
      </el-dropdown>
    </template>
    <el-upload
      v-else-if="type === 'expand'"
      class="expand-upload"
      :class="itemType"
      :name="name"
      style="width: 100%"
      :headers="headers"
      :action="action"
      :data="data"
      :limit="limit"
      :disabled="disabled || fileList.length >= limit"
      :multiple="multiple"
      :accept="accept"
      :show-file-list="false"
      :file-list="fileList"
      :before-upload="beforeUpload"
      :before-remove="beforeRemove"
      :on-exceed="onUploadLimit"
      :on-success="onUploadSuccess"
      :on-remove="onRemoveFile"
      :on-error="onUploadError"
    >
      <el-row v-if="itemType === 'card'" type="flex" style="flex-wrap: wrap">
        <div ref="uploadBtn" style="width: 0px; height: 0px; border: none" />
      </el-row>
      <div v-else class="upload-file-list">
        <!-- 文本样式 -->
        <el-button :size="size" :disabled="disabled || fileList.length >= limit" type="primary">
          点击上传
        </el-button>
      </div>
    </el-upload>
    <el-row v-if="type === 'expand' && itemType === 'card'" type="flex" style="flex-wrap: wrap">
      <!-- 卡片样式 -->
      <UploadFileList
        :supportPreview="supportPreview"
        :supportDownload="supportDownload"
        :file-list="fileList"
        :type="itemType"
        :direction="direction"
        @remove="onDeleteFile"
        @add="onAddFile"
      >
        <div v-if="fileList.length < limit || limit === 0 || limit == null">
          <i class="el-icon-plus" style="font-size: 18px" />
        </div>
      </UploadFileList>
    </el-row>
    <UploadFileList
      v-if="type === 'expand' && itemType === 'text'"
      :supportPreview="supportPreview"
      :supportDownload="supportDownload"
      :file-list="fileList"
      :type="itemType"
      :direction="direction"
      style="margin-top: 8px"
      @remove="onDeleteFile"
    />
    <PreviewDialog
      v-if="showPreview"
      :visible="showPreview"
      :file-list="fileList"
      :defaultIndex="fileIndex"
      :readonly="!supportDownload"
      @close="showPreview = false"
    />
  </div>
</template>

<script>
import { getFileType } from '@/utils';
import { uploadMixin } from '@/core/mixins';
import { UploadWidget } from '@/utils/widget.js';
import UploadFileList from '@/components/CustomUpload/UploadFileList.vue';
import PreviewDialog from '@/components/FilePreview/PreviewDialog.vue';

export default {
  name: 'CustomUpload',
  props: {
    value: {
      type: Array,
      default: () => []
    },
    size: {
      type: String,
      default: 'small'
    },
    // 上传组件显示类型，download / expand
    type: {
      type: String,
      default: 'dropdown'
    },
    // 上传文件显示类型，card / text
    itemType: {
      type: String,
      default: 'card'
    },
    // 上传文件列表展示方向，horizontal / vertical
    direction: {
      type: String,
      default: 'vertical'
    },
    // 是否支持文件预览
    supportPreview: {
      type: Boolean,
      default: true
    },
    // 是否支持文件下载
    supportDownload: {
      type: Boolean,
      default: true
    },
    // 上传文件个数限制
    limit: {
      type: Number
    },
    // 是否禁用
    disabled: {
      type: Boolean,
      default: false
    },
    // 上传文件地址
    action: {
      type: String
    },
    // 上传文件头部信息
    headers: {
      type: Object
    },
    // 是否支持多选
    multiple: {
      type: Boolean,
      default: false
    },
    // 上传文件额外数据
    data: {
      type: Object
    },
    // 上传文件字段名
    name: {
      type: String,
      default: 'file'
    },
    // 上传文件类型
    accept: {
      type: String
    },
    // 上传文件前事件
    beforeUpload: {
      type: Function
    },
    // 移除文件前事件
    beforeRemove: {
      type: Function
    },
    // 上传文件成功事件
    onExceed: {
      type: Function
    }
  },
  components: {
    UploadFileList,
    PreviewDialog
  },
  mixins: [uploadMixin],
  data() {
    return {
      showPopover: false,
      showPreview: false,
      fileIndex: 0,
      uploadWidget: new UploadWidget(this.limit)
    };
  },
  computed: {
    fileList() {
      return (this.value || []).map(item => {
        return {
          ...item,
          type: getFileType(item.name)
        };
      });
    }
  },
  methods: {
    onPreviewClick(file, fileList) {
      if (this.supportPreview) {
        this.fileIndex = fileList.findIndex(item => item.url === file.url);
        this.$nextTick(() => {
          this.showPreview = true;
        });
      } else if (this.supportDownload) {
        this.downloadFile(file.url, file.name);
      }
    },
    onUploadSuccess(response, file, fileList) {
      if (response.success) {
        file.downloadUri = response.data.downloadUri;
        file.filename = response.data.filename;
        file.uploadPath = response.data.uploadPath;
        file.url = URL.createObjectURL(file.raw);
        this.uploadWidget.onFileChange(file, fileList);
        this.onChange(this.uploadWidget.fileList);
        this.$emit('success', response, file, fileList);
      } else {
        this.$message.error(response.message);
        this.$emit('error', response, file, fileList);
      }
    },
    onRemoveFile(file, fileList) {
      if (file != null && fileList != null) {
        fileList = fileList.filter(item => item.url !== file.url);
      }
      console.log('file', file, fileList);
      this.uploadWidget.onFileChange(file, fileList);
      this.onChange(this.uploadWidget.fileList);
      this.$emit('remove', file, fileList);
    },
    onUploadError(e, file, fileList) {
      this.$message.error('文件上传失败');
    },
    onUploadLimit(file, fileList) {
      if (this.onExceed && typeof this.onExceed === 'function') {
        this.onExceed(file, fileList);
      } else {
        this.$message.error('已经超出最大上传个数限制');
      }
    },
    onDeleteFile(file, fileList) {
      this.uploadWidget.onFileChange(file, fileList);
      this.onChange(this.uploadWidget.fileList);
      this.$emit('remove', file, fileList);
    },
    onAddFile() {
      if (this.$refs.uploadBtn) {
        this.$refs.uploadBtn.click();
      }
    },
    onChange(value) {
      this.$emit('input', value);
      this.$emit('change', value);
    }
  },
  watch: {
    value: {
      handler(value) {
        this.uploadWidget.fileList = value;
      },
      immediate: true
    }
  }
};
</script>

<style lang="scss" scoped>
@import '@/assets/style/element-variables.scss';

.custom-upload .el-dropdown ::v-deep .el-button-group .el-button:first-child {
  padding: 0px;
}

.upload-btn {
  display: flex;
  align-items: center;
  padding: 9px 16px;
}
.upload-btn .file-count {
  height: 12px;
  line-height: 12px;
  min-width: 12px;
  color: white;
  font-size: 12px;
  background: #f56c6c;
  border-radius: 6px;
  padding: 0px 3px;
  margin-left: 5px;
}
.hide-list ::v-deep .el-dropdown__caret-button {
  display: none;
}
.dropdown-file-item {
  min-width: 200px;
  height: 36px;
  line-height: 36px;
}

.dropdown-file-item span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.expand-upload.card {
  height: 0px !important;
}

::v-deep .el-dropdown-menu__item {
  padding: 0px 12px;
}
::v-deep .el-dropdown-menu__item:not(.is-disabled):hover,
::v-deep .el-dropdown-menu__item:not(.is-disabled):hover i,
::v-deep .el-dropdown-menu__item:focus,
::v-deep .el-dropdown-menu__item:focus i {
  background-color: white;
  color: $--color-primary;
}
::v-deep .el-dropdown-menu__item i {
  color: #d8d8d8;
}
</style>
